﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp;
using Abp.Domain.Repositories;
using Abp.ObjectMapping;
using AutoMapper.QueryableExtensions;
using FwProject.Com.Dto;
using FwProject.ShopApplication;
using FwProject.ShoppingMall.Com;
using FwProject.ShoppingMall.Shop;
using X.PagedList;

namespace FwProject.Com
{
    public class ShopOrderDetailsAppService : FwProjectAppServiceBase, IShopOrderDetailsAppService
    {
        private readonly IRepository<ShopOrderDetails, Guid> _repositoryShopOrderDetails;
        private readonly IRepository<ShopProduct, Guid> _repositoryShopProduct;
        private readonly IRepository<ShopSupplier, Guid> _repositoryShopSupplier;
        private readonly IRepository<ShopOrder, Guid> _repositoryShopOrder;
        private IGuidGenerator _guid { get; set; }
        public IObjectMapper _map { get; set; }
        public ShopOrderDetailsAppService(IRepository<ShopOrderDetails, Guid> repositoryShopOrderDetails, IRepository<ShopProduct, Guid> repositoryShopProduct, IRepository<ShopSupplier, Guid> repositoryShopSupplier, IRepository<ShopOrder, Guid> repositoryShopOrder)
        {
            _repositoryShopOrderDetails = repositoryShopOrderDetails;
            _repositoryShopProduct = repositoryShopProduct;
            _repositoryShopSupplier = repositoryShopSupplier;
            _repositoryShopOrder = repositoryShopOrder;
            _guid = SequentialGuidGenerator.Instance;
        }


        #region 后台管理
        /// <summary>
        /// 获取供货商的订单列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public LayerDataBaseDto GetSupplierOrdersData(int page, int limit, string supplierName, string settlementStatus)
        {
            var query = _repositoryShopOrderDetails.GetAll().Where(o => o.DeliveryStatus == DeliveryStatus.已发货 || o.DeliveryStatus == DeliveryStatus.已确认).Join(_repositoryShopProduct.GetAll(), i => i.ShopproductId, j => j.Id, (i, j) => new
            {
                i.Id,
                i.OrderNumber,
                i.CreationTime,
                i.ShopproductId,
                j.ProductName,
                SupplierId = j.ShopSupplierid,
                i.ProductCount,
                i.PayPrice,
                j.SpcecostPrice,
                TotalPrice = i.ProductCount * i.PayPrice,
                i.DeliveryStatus,
                i.DeliveryTime,
                i.EvaluateStatus,
                i.PriceDifference,
                i.Returngoods,
                i.SettlementStatus,
                i.SettlementTime,
            }).Join(_repositoryShopSupplier.GetAll(), i => i.SupplierId, j => j.Id, (i, j) => new SupplierOrdersDto
            {
                Id = i.Id,
                OrderNumber = i.OrderNumber,
                OrderTime = i.CreationTime,
                ShopproductId = i.ShopproductId,
                ProductName = i.ProductName,
                SupplierId = i.SupplierId,
                SupplierName = j.SupplierName,
                ProductCount = i.ProductCount,
                PayPrice = i.PayPrice,
                SpcecostPrice = i.SpcecostPrice,
                TotalPrice = i.TotalPrice,
                DeliveryStatus = i.DeliveryStatus,
                DeliveryTime = i.DeliveryTime,
                EvaluateStatus = i.EvaluateStatus,
                PriceDifference = i.PriceDifference,
                Returngoods = i.Returngoods,
                SettlementStatus = i.SettlementStatus,
                SettlementTime = i.SettlementTime
            });

            if (!string.IsNullOrEmpty(supplierName))
                query = query.Where(o => o.SupplierName == supplierName).OrderByDescending(o => o.DeliveryTime);
            if (settlementStatus == "0")
            {
                query = query.Where(o => o.SettlementStatus == SettlementStatus.未结算).OrderByDescending(o => o.DeliveryTime);
            }
            else if (settlementStatus == "1")
            {
                query = query.Where(o => o.SettlementStatus == SettlementStatus.已结算).OrderByDescending(o => o.DeliveryTime);
            }

            var listmodel = query.OrderByDescending(o => o.DeliveryTime).ToPagedList(page, limit);
            LayerDataBaseDto dto = new LayerDataBaseDto();
            dto.Data = listmodel;
            dto.Count = listmodel.TotalItemCount;
            return dto;
        }
        /// <summary>
        /// 根据订单id获取订单明细
        /// </summary>
        /// <param name="OrderId"></param>
        /// <returns></returns>
        public async Task<List<ShopOrderDetailsDto>> GetShopOrderDetailsByOrderIdAsync(Guid OrderId)
        {
            var list = _repositoryShopOrderDetails.GetAll().Where(o=>o.OrderId==OrderId);
            return await list.ProjectTo<ShopOrderDetailsDto>().ToListAsync();
        }

        /// <summary>
        /// 根据结账编号获取订单明细
        /// </summary>
        /// <param name="settlementId"></param>
        /// <returns></returns>
        public async Task<List<ShopOrderDetailsDto>> GetOrderDetailsBySettlementIdAsync(Guid settlementId)
        {
            var model = (await _repositoryShopOrderDetails.GetAllListAsync()).Where(o => o.SettlementId == settlementId).AsQueryable();
            return await model.ProjectTo<ShopOrderDetailsDto>().ToListAsync();
        }

        /// <summary>
        /// 供货商订单导出
        /// </summary>
        /// <param name="supplierName"></param>
        /// <param name="settlementStatus"></param>
        /// <returns></returns>
        public List<SupplierOrdersDto> GetExportSupplierOrderData(string supplierName, string settlementStatus)
        {
            var query = _repositoryShopOrderDetails.GetAll().Where(o => o.DeliveryStatus == DeliveryStatus.已发货 || o.DeliveryStatus == DeliveryStatus.已确认).Join(_repositoryShopProduct.GetAll(), i => i.ShopproductId, j => j.Id, (i, j) => new
            {
                i.Id,
                i.OrderNumber,
                i.CreationTime,
                i.ShopproductId,
                j.ProductName,
                SupplierId = j.ShopSupplierid,
                i.ProductCount,
                i.PayPrice,
                TotalPrice = i.ProductCount * i.PayPrice,
                i.DeliveryStatus,
                i.DeliveryTime,
                i.EvaluateStatus,
                i.PriceDifference,
                i.Returngoods,
                i.SettlementStatus,
                i.SettlementTime,
            }).Join(_repositoryShopSupplier.GetAll(), i => i.SupplierId, j => j.Id, (i, j) => new SupplierOrdersDto
            {
                Id = i.Id,
                OrderNumber = i.OrderNumber,
                OrderTime = i.CreationTime,
                ShopproductId = i.ShopproductId,
                ProductName = i.ProductName,
                SupplierId = i.SupplierId,
                SupplierName = j.SupplierName,
                ProductCount = i.ProductCount,
                PayPrice = i.PayPrice,
                TotalPrice = i.TotalPrice,
                DeliveryStatus = i.DeliveryStatus,
                DeliveryTime = i.DeliveryTime,
                EvaluateStatus = i.EvaluateStatus,
                PriceDifference = i.PriceDifference,
                Returngoods = i.Returngoods,
                SettlementStatus = i.SettlementStatus,
                SettlementTime = i.SettlementTime
            });

            var listmodel = query.OrderByDescending(o => o.DeliveryTime);

            if (!string.IsNullOrEmpty(supplierName))
                listmodel = listmodel.Where(o => o.SupplierName == supplierName).OrderByDescending(o => o.DeliveryTime);
            if (settlementStatus == "0")
                listmodel = listmodel.Where(o => o.SettlementStatus == SettlementStatus.未结算).OrderByDescending(o => o.DeliveryTime);
            if (settlementStatus == "1")
                listmodel = listmodel.Where(o => o.SettlementStatus == SettlementStatus.已结算).OrderByDescending(o => o.DeliveryTime);

            return listmodel.ToList();
        }
        /// <summary>
        /// 获取当月的收款金额、退款金额、实际金额
        /// </summary>
        /// <returns></returns>
        public ShopOrderTotalPriceDto GetTotalPrice()
        {
            var entity = _repositoryShopOrder.GetAll().Where(o => o.PayStatus == PayStatus.已支付 && o.CreationTime.Year == DateTime.Now.Year && o.CreationTime.Month == DateTime.Now.Month);
            decimal SumTotalPrice = 0;
            decimal SumReturnPrice = 0;
            decimal SumPrice = 0;
            foreach (var item in entity)
            {
                var list = _repositoryShopOrderDetails.GetAll().Where(o => o.OrderId == item.Id);
                SumTotalPrice += list.Sum(o => o.PayAmountPrice);
                SumReturnPrice += list.Sum(o => o.ReturngoodsPrice);
                SumPrice += list.Sum(o => o.PayAmountPrice) - list.Sum(o => o.ReturngoodsPrice);
            }

            ShopOrderTotalPriceDto model = new ShopOrderTotalPriceDto()
            {
                TotalPrice = SumTotalPrice,
                ReturnPrice = SumReturnPrice,
                Price = SumPrice
            };
            return model;
        }
        /// <summary>
        /// 获取当月已支付的订单明细
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public async Task<LayerDataBaseDto> GetSaleDetailsAsync(int page, int limit)
        {
            var entity = _repositoryShopOrder.GetAll().Where(o => o.PayStatus == PayStatus.已支付 && o.CreationTime.Year == DateTime.Now.Year && o.CreationTime.Month == DateTime.Now.Month);
            var data = await entity.Join(_repositoryShopOrderDetails.GetAll(), a => a.Id, b => b.OrderId, (a, b) => new
            {
                b.ShopproductId,
                b.ShopName,
                b.ShopSkuId,
                b.SkuName,
                b.ProductCount,
                b.PayPrice,
                b.PayAmountPrice,
                b.CreationTime
            }).OrderByDescending(o => o.CreationTime).ToPagedListAsync(page, limit);
            LayerDataBaseDto dto = new LayerDataBaseDto();
            dto.Data = data;
            dto.Count = data.TotalItemCount;
            return dto;
        }
        /// <summary>
        /// 获取商品销售明细
        /// </summary>
        /// <returns></returns>
        public async Task<LayerDataBaseDto> GetShopSaleDetailsAsync(int page, int limit, string CreationTime)
        {
            var entity = _repositoryShopOrder.GetAll().Where(o => o.PayStatus == PayStatus.已支付);
            if (!string.IsNullOrEmpty(CreationTime))
            {
                DateTime beginTime = new DateTime();
                DateTime endTime = new DateTime();
                var time = CreationTime.Split('~');
                if (time.Count() == 2)
                {
                    beginTime = Convert.ToDateTime(time[0].Trim());
                    endTime = Convert.ToDateTime(time[1].Trim());
                }
                entity = entity.Where(o=>o.CreationTime>=beginTime && o.CreationTime<=endTime.AddHours(24));
            }
            else
            {
                entity = entity.Where(o => o.PayStatus == PayStatus.已支付 && o.CreationTime.Year == DateTime.Now.Year && o.CreationTime.Month == DateTime.Now.Month);
            }
            var data = await entity.Join(_repositoryShopOrderDetails.GetAll(), a => a.Id, b => b.OrderId, (a, b) => new
            {
                b.ShopproductId,
                b.ProductCount,
                b.PayAmountPrice,

            }).GroupBy(o => o.ShopproductId).Select(b => new
            {
                ShopproductId = b.Key,
                PayAmountPrice = b.Sum(c => c.PayAmountPrice),
                PayOrderCount = b.Count(),
                ProductCount = b.Sum(c => c.ProductCount)
            }).Join(_repositoryShopProduct.GetAll(), a => a.ShopproductId, b => b.Id, (a, b) => new
            {
                a.ShopproductId,
                a.ProductCount,
                a.PayAmountPrice,
                a.PayOrderCount,
                b.ProductName

            }).OrderByDescending(o => o.PayOrderCount).ToPagedListAsync(page, limit);

            LayerDataBaseDto dto = new LayerDataBaseDto();
            dto.Data = data;
            dto.Count = data.TotalItemCount;
            return dto;
        }
        /// <summary>
        /// 热卖商品排行
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public async Task<LayerDataBaseDto> GetHotSellingCommodityListAsync(int page, int limit)
        {
            var data = await _repositoryShopOrder.GetAll().Where(o => o.PayStatus == PayStatus.已支付).Join(_repositoryShopOrderDetails.GetAll(), a => a.Id, b => b.OrderId, (a, b) => new
            {
                b.ShopproductId,
                b.PayAmountPrice
            }).GroupBy(o => o.ShopproductId).Select(p => new
            {
                ShopproductId = p.Key,
                OrderCount = p.Count(),
                PayAmountPrice = p.Sum(q => q.PayAmountPrice)
            }).Join(_repositoryShopProduct.GetAll(), a => a.ShopproductId, b => b.Id, (a, b) => new
            {
                b.ProductName,
                b.MarketPrice,
                a.OrderCount,
                a.PayAmountPrice
            }).OrderByDescending(o => o.OrderCount).Take(10).ToPagedListAsync(page, limit);

            LayerDataBaseDto dto = new LayerDataBaseDto();
            dto.Data = data;
            dto.Count = data.TotalItemCount;
            return dto;
        }

        public async Task<List<HotSellingCommdityDto>> GetHotSellingCommodityReportAsync()
        {
            var data = await _repositoryShopOrder.GetAll().Where(o => o.PayStatus == PayStatus.已支付).Join(_repositoryShopOrderDetails.GetAll(), a => a.Id, b => b.OrderId, (a, b) => new
            {
                b.ShopproductId,
                b.PayAmountPrice
            }).GroupBy(o => o.ShopproductId).Select(p => new
            {
                ShopproductId = p.Key,
                OrderCount = p.Count(),
                PayAmountPrice = p.Sum(q => q.PayAmountPrice)
            }).Join(_repositoryShopProduct.GetAll(), a => a.ShopproductId, b => b.Id, (a, b) => new HotSellingCommdityDto
            {
                ProductName = b.ProductName,
                OrderCount = a.OrderCount,
                PayAmountPrice = a.PayAmountPrice
            }).OrderByDescending(o => o.OrderCount).Take(10).ToListAsync();

            return data;
        }

        #endregion
    }
}
